package itsen.com.bduidemo.modle.event.scroller;

import android.content.Context;
import android.support.v4.view.ViewConfigurationCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

import itsen.com.bduidemo.lib.tool.LogTool;


/**
 * Created by 周德森
 * Created time 2017/7/17 22:12
 * Description:DNui
 * Version: V 1.0
 */

public class ScrollerLayout extends ViewGroup {

    /**
     * 用于完成滚动操作的实例
     */
    private Scroller mScroller;

    /**
     * 判定为拖动的最小移动像素数
     */
    private int mTouchSlop;

    /**
     * 手机按下时的屏幕坐标
     */
    private float mXDown;

    /**
     * 手机当时所处的屏幕坐标
     */
    private float mXMove;

    /**
     * 上次触发ACTION_MOVE事件时的屏幕坐标
     */
    private float mXLastMove;

    /**
     * 界面可滚动的左边界
     */
    private int leftBorder;

    /**
     * 界面可滚动的右边界
     */
    private int rightBorder;

    /**
     * 速度
     */
    private VelocityTracker mVelocityTracker;
    private float speedx;

    public ScrollerLayout(Context context, AttributeSet attrs) {
        super(context);
        // 第一步，创建Scroller的实例
        mScroller = new Scroller(context);
        ViewConfiguration configuration = ViewConfiguration.get(context);
        // 获取TouchSlop值
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            // 为ScrollerLayout中的每一个子控件测量大小
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed){
            int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                View childView  = getChildAt(i);
                // 为ScrollerLayout中的每一个子控件在水平方向上进行布局
                childView.layout(i * childView.getMeasuredWidth(),0,
                        (i+1)*childView.getMeasuredWidth(),childView.getMeasuredHeight());
            }

            // 初始化左右边界值
            leftBorder = getChildAt(0).getLeft();
            rightBorder = getChildAt(getChildCount() - 1).getRight();
        }
    }

    /**
     * 事件拦截，一旦这个返回true,事件被拦截，将事件交给改viewGroup的onTouchEvent处理
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //获取手指按下的坐标
                mXDown = ev.getRawX();
                mXLastMove = mXDown;
                LogTool.e("mXDown","-- "+mXDown);
                break;
            case MotionEvent.ACTION_MOVE:
                mXMove = ev.getRawX();
                float diff = Math.abs(mXMove - mXDown);
                LogTool.e("diff","-- "+diff);
                mXLastMove = mXMove;
                // 当手指拖动值大于TouchSlop值时，认为应该进行滚动，拦截子控件的事件
                if (diff > mTouchSlop) {
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mVelocityTracker == null){
            mVelocityTracker = VelocityTracker.obtain();
        }else {
            mVelocityTracker.clear();
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                break;
            case MotionEvent.ACTION_MOVE:
                mVelocityTracker.addMovement(event);//绑定获取速度
                mVelocityTracker.computeCurrentVelocity(1000);
                speedx = mVelocityTracker.getXVelocity();
                LogTool.e("speedx:"+mVelocityTracker.getXVelocity());

                mXMove = event.getRawX();//当前手指在屏幕中的坐标
                //LogTool.e("move"+event.getHistoricalY(0));
                 LogTool.e("mXMove","："+mXMove);
                int scrolledX = (int) (mXLastMove - mXMove); //--增量
                LogTool.e("scrolledX","："+scrolledX);
                if (getScrollX() + scrolledX < leftBorder) {  //判断左边是否越界
                    scrollTo(leftBorder, 0);
                    return true;
                } else if (getScrollX() + getWidth() + scrolledX > rightBorder) {  //判断右边是否越界
                    scrollTo(rightBorder - getWidth(), 0);
                    return true;
                }
                //跟随手指移动
                scrollBy(scrolledX, 0);
                mXLastMove = mXMove;//把当前移动到的位置赋给上一次移动到的位置  --使得scrolledX 为增量
                break;
            case MotionEvent.ACTION_UP:
                // 当手指抬起时，根据当前的滚动值来判定应该滚动到哪个子控件的界面
                int targetIndex = (getScrollX() + getWidth() / 2) / getWidth();
                int dx = targetIndex * getWidth() - getScrollX();
                // 第二步，调用startScroll()方法来初始化滚动数据并刷新界面
                mScroller.startScroll(getScrollX(), 0, dx, 0);
                invalidate();
                LogTool.e("speedx2:"+mVelocityTracker.getXVelocity());
                break;
            case MotionEvent.ACTION_CANCEL:
                mVelocityTracker.recycle();
                break;
        }
         return super.onTouchEvent(event);
        //return true;
    }


    @Override
    public void computeScroll() {
        // 第三步，重写computeScroll()方法，并在其内部完成平滑滚动的逻辑
        if (mScroller.computeScrollOffset()) {
            LogTool.e("getCurrX:"+mScroller.getCurrX()+"/Children"+getChildAt(0).getLeft());
            LogTool.e("getCurrY:"+mScroller.getCurrY());
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }

}

/***********************API****************************
mScroller.getCurrX() //获取mScroller当前水平滚动的位置
mScroller.getCurrY() //获取mScroller当前竖直滚动的位置
mScroller.getFinalX() //获取mScroller最终停止的水平位置
mScroller.getFinalY() //获取mScroller最终停止的竖直位置
mScroller.setFinalX(int newX) //设置mScroller最终停留的水平位置，没有动画效果，直接跳到目标位置
mScroller.setFinalY(int newY) //设置mScroller最终停留的竖直位置，没有动画效果，直接跳到目标位置

//滚动，startX, startY为开始滚动的位置，dx,dy为滚动的偏移量, duration为完成滚动的时间
mScroller.startScroll(int startX, int startY, int dx, int dy) //使用默认完成时间250ms
mScroller.startScroll(int startX, int startY, int dx, int dy, int duration)
//
mScroller.computeScrollOffset() //返回值为boolean，true说明滚动尚未完成，false说明滚动已经完成。这是一个很重要的方法，通常放在View.computeScroll()中，用来判断是否滚动是否结束。
 computeScroll


 public void fling (int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)
 　　在fling（译者注：快滑，用户按下触摸屏、快速移动后松开）手势基础上开始滚动。滚动的距离取决于fling的初速度。
 　　参数
 　　startX 滚动起始点X坐标
 　　startY 滚动起始点Y坐标
 　　velocityX   当滑动屏幕时X方向初速度，以每秒像素数计算
 　　velocityY   当滑动屏幕时Y方向初速度，以每秒像素数计算
 　　minX    X方向的最小值，scroller不会滚过此点。
 　　maxX    X方向的最大值，scroller不会滚过此点。
 　　minY    Y方向的最小值，scroller不会滚过此点。
 　　maxY    Y方向的最大值，scroller不会滚过此点。

 */
